/** * Copyright (c) 2014 - 2017 Frank Appel * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Frank Appel - initial API and implementation */ package com.codeaffine.eclipse.swt.widget.scrollable; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; import com.codeaffine.eclipse.swt.widget.scrollbar.FlatScrollBar; class TableVerticalScrollBarUpdater implements ScrollBarUpdater { private final FlatScrollBar scrollBar; private final Table table; TableVerticalScrollBarUpdater( Table table, FlatScrollBar scrollBar ) { this.scrollBar = scrollBar; this.table = table; } @Override public void update() { int itemCount = table.getItemCount(); scrollBar.setIncrement( 1 * SELECTION_RASTER_SMOOTH_FACTOR ); scrollBar.setMaximum( itemCount * SELECTION_RASTER_SMOOTH_FACTOR ); scrollBar.setMinimum( 0 ); scrollBar.setPageIncrement( calculateThumb() ); scrollBar.setThumb( calculateThumb() ); scrollBar.setSelection( calculateSelection() ); } private int calculateSelection() { if( table.getItemCount() > 0 ) { int topIndex = table.getTopIndex(); return cornerCaseWorkaroundForGtk( topIndex, table.getItem( topIndex ) ) * SELECTION_RASTER_SMOOTH_FACTOR; } return 0; } int calculateThumb() { int height = calculateHeight(); return SELECTION_RASTER_SMOOTH_FACTOR * ( height / table.getItemHeight() ); } int calculateHeight() { int result = table.getClientArea().height; if( table.getHeaderVisible() ) { result -= table.getHeaderHeight(); } return result; } // [fappel]: setting topItemIndex does not work reliable on gtk for last selection items // if top item is only half visible. The table is moved correctly but top item index returns the old value. // This recognizes such a situation and increases the flat scrollbar selection anyway. private static int cornerCaseWorkaroundForGtk( int selection, TableItem topItem ) { return topItem != null && topItem.getBounds().y < 0 ? selection + 1 : selection; } }