| package org.eclipse.nebula.widgets.nattable.renderer.swt.layer.viewport |
| |
| import java.math.BigDecimal |
| import org.eclipse.nebula.widgets.nattable.core.layer.impl.viewport.ViewportAxis |
| import org.eclipse.swt.widgets.Event |
| import org.eclipse.swt.widgets.Listener |
| import org.eclipse.swt.widgets.ScrollBar |
| |
| import static extension java.lang.Math.* |
| import static extension org.eclipse.nebula.widgets.nattable.core.big.layer.axis.BigAxisInvariants.* |
| |
| class ScrollBarHandler implements Listener { |
| |
| val public static MAX_SCROLL_SIZE = 10000000 // SWT ScrollBar doesn't function properly when the range is > 10 billion |
| val static BD_MAX_SCROLL_SIZE = new BigDecimal(MAX_SCROLL_SIZE) |
| |
| // |
| |
| val ScrollBar scrollBar |
| val ViewportAxis viewportAxis |
| |
| val BigDecimal minThumbSize |
| val int minIncrement |
| val int minPageIncrement |
| |
| boolean isScrollBarVisible = true |
| |
| new(ScrollBar scrollBar, ViewportAxis viewportAxis) { |
| this.scrollBar = scrollBar |
| this.viewportAxis = viewportAxis |
| |
| scrollBar.thumb = 0 |
| scrollBar.increment = 0 |
| scrollBar.pageIncrement = 0 |
| |
| minThumbSize = new BigDecimal(1.max(scrollBar.thumb)) |
| minIncrement = 1.max(scrollBar.increment) |
| minPageIncrement = 1.max(scrollBar.pageIncrement) |
| } |
| |
| def getMinThumbSize() { minThumbSize } |
| def getMinIncrement() { minIncrement } |
| def getMinPageIncrement() { minPageIncrement } |
| |
| def setScrollBarVisible(boolean isScrollBarVisible) { |
| this.isScrollBarVisible = isScrollBarVisible |
| } |
| |
| /** |
| * SWT event handler |
| */ |
| override handleEvent(Event event) { |
| updateViewportOrigin |
| } |
| |
| /** |
| * Update the viewportAxis' origin from the scrollbar selection. |
| */ |
| def void updateViewportOrigin() { |
| val visiblePixelSize = viewportAxis.visiblePixelSize |
| val maxPixelSize = viewportAxis.underlyingAxis.pixelSize |
| val maxScrollSize = maxPixelSize.min(BD_MAX_SCROLL_SIZE) |
| val thumbSize = minThumbSize.max((visiblePixelSize / maxPixelSize) * maxScrollSize) |
| |
| val intPerPixelRatio = |
| if (thumbSize / maxScrollSize < visiblePixelSize / maxPixelSize) |
| thumbSize / visiblePixelSize |
| else |
| if (maxScrollSize + thumbSize < BD_MAX_SCROLL_SIZE) |
| maxScrollSize / maxPixelSize |
| else |
| (maxScrollSize - thumbSize) / (maxPixelSize - visiblePixelSize) |
| |
| viewportAxis.viewportOrigin = new BigDecimal(scrollBar.selection) / intPerPixelRatio |
| } |
| |
| /** |
| * Recalculate scrollbar values from viewport axis values. |
| */ |
| def void recalculateScrollBarSize() { |
| val visiblePixelSize = viewportAxis.visiblePixelSize |
| val maxPixelSize = viewportAxis.underlyingAxis.pixelSize |
| val maxScrollSize = maxPixelSize.min(BD_MAX_SCROLL_SIZE) |
| val thumbSize = minThumbSize.max((visiblePixelSize / maxPixelSize) * maxScrollSize) |
| |
| val intPerPixelRatio = |
| if (thumbSize / maxScrollSize < visiblePixelSize / maxPixelSize) |
| thumbSize / visiblePixelSize |
| else |
| if (maxScrollSize + thumbSize < BD_MAX_SCROLL_SIZE) |
| maxScrollSize / maxPixelSize |
| else |
| (maxScrollSize - thumbSize) / (maxPixelSize - visiblePixelSize) |
| |
| val viewportOrigin = viewportAxis.viewportOrigin |
| |
| if (visiblePixelSize > BigDecimal::ZERO && viewportOrigin < maxPixelSize) { |
| scrollBar.maximum = maxScrollSize.intValue |
| scrollBar.thumb = thumbSize.intValue |
| scrollBar.pageIncrement = Math::max(minPageIncrement, thumbSize.intValue) |
| |
| // Increment by size of segment 0 or 1/4 of visible pixel size, whichever is smaller |
| val pixelIncrement = viewportAxis.getPixelSizeOfSegmentPosition(0).min(visiblePixelSize.doubleValue / 4) |
| scrollBar.increment = minIncrement.max((pixelIncrement * intPerPixelRatio).intValue) |
| |
| scrollBar.selection = (viewportOrigin * intPerPixelRatio).intValue |
| |
| scrollBar.enabled = true |
| scrollBar.visible = isScrollBarVisible |
| } else { |
| scrollBar.enabled = false |
| scrollBar.visible = false |
| } |
| } |
| |
| } |