blob: 1a86775e66d4aa9df2aa48edc19125d6ec495105 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013 EclipseSource and others.
* 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:
* EclipseSource - initial API and implementation
******************************************************************************/
package org.eclipse.swt.internal.widgets.treecolumnkit;
import static org.eclipse.rap.rwt.lifecycle.WidgetUtil.getAdapter;
import java.util.Arrays;
import org.eclipse.rap.json.JsonObject;
import org.eclipse.rap.rwt.internal.protocol.WidgetOperationHandler;
import org.eclipse.rap.rwt.lifecycle.ProcessActionRunner;
import org.eclipse.swt.SWT;
import org.eclipse.swt.internal.widgets.ITreeAdapter;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
public class TreeColumnOperationHandler extends WidgetOperationHandler<TreeColumn> {
private static final String METHOD_MOVE = "move";
private static final String METHOD_RESIZE = "resize";
private static final String PROP_LEFT = "left";
private static final String PROP_WIDTH = "width";
public TreeColumnOperationHandler( TreeColumn column ) {
super( column );
}
@Override
public void handleCall( TreeColumn column, String method, JsonObject properties ) {
if( method.equals( METHOD_MOVE ) ) {
handleCallMove( column, properties );
} else if( method.equals( METHOD_RESIZE ) ) {
handleCallResize( column, properties );
}
}
@Override
public void handleNotify( TreeColumn column, String eventName, JsonObject properties ) {
if( "Selection".equals( eventName ) ) {
handleNotifySelection( column, properties );
} else if( "DefaultSelection".equals( eventName ) ) {
handleNotifyDefaultSelection( column, properties );
} else {
super.handleNotify( column, eventName, properties );
}
}
/*
* PROTOCOL CALL move
*
* @left (int) the left position of the column
*/
public void handleCallMove( final TreeColumn column, JsonObject properties ) {
final int newLeft = properties.get( PROP_LEFT ).asInt();
ProcessActionRunner.add( new Runnable() {
public void run() {
moveColumn( column, newLeft );
}
} );
}
/*
* PROTOCOL CALL resize
*
* @width (int) the width of the column
*/
public void handleCallResize( final TreeColumn column, JsonObject properties ) {
final int width = properties.get( PROP_WIDTH ).asInt();
ProcessActionRunner.add( new Runnable() {
public void run() {
column.setWidth( width );
}
} );
}
/*
* PROTOCOL NOTIFY Selection
*
* @param altKey (boolean) true if the ALT key was pressed
* @param ctrlKey (boolean) true if the CTRL key was pressed
* @param shiftKey (boolean) true if the SHIFT key was pressed
*/
public void handleNotifySelection( TreeColumn column, JsonObject properties ) {
Event event = createSelectionEvent( SWT.Selection, properties );
column.notifyListeners( SWT.Selection, event );
}
/*
* PROTOCOL NOTIFY DefaultSelection
*
* @param altKey (boolean) true if the ALT key was pressed
* @param ctrlKey (boolean) true if the CTRL key was pressed
* @param shiftKey (boolean) true if the SHIFT key was pressed
*/
public void handleNotifyDefaultSelection( TreeColumn column, JsonObject properties ) {
Event event = createSelectionEvent( SWT.DefaultSelection, properties );
column.notifyListeners( SWT.DefaultSelection, event );
}
static void moveColumn( TreeColumn column, int newLeft ) {
Tree tree = column.getParent();
int targetColumn = findMoveTarget( tree, newLeft );
int[] columnOrder = tree.getColumnOrder();
int index = tree.indexOf( column );
int orderIndex = arrayIndexOf( columnOrder, index );
columnOrder = arrayRemove( columnOrder, orderIndex );
if( orderIndex < targetColumn ) {
targetColumn--;
}
if( isFixed( column ) || isFixed( tree.getColumn( targetColumn ) ) ) {
targetColumn = tree.indexOf( column );
}
columnOrder = arrayInsert( columnOrder, targetColumn, index );
if( Arrays.equals( columnOrder, tree.getColumnOrder() ) ) {
// TODO [rh] HACK mark left as changed
TreeColumn[] columns = tree.getColumns();
for( int i = 0; i < columns.length; i++ ) {
getAdapter( columns[ i ] ).preserve( PROP_LEFT, null );
}
} else {
tree.setColumnOrder( columnOrder );
// [if] HACK mark left as changed - see bug 336340
getAdapter( column ).preserve( PROP_LEFT, null );
}
}
/* (intentionally non-JavaDoc'ed)
* Returns the index in the columnOrder array at which the moved column
* should be inserted (moving remaining columns to the right). A return
* value of columnCount indicates that the moved column should be inserted
* after the right-most column.
*/
private static int findMoveTarget( Tree tree, int newLeft ) {
int result = -1;
TreeColumn[] columns = tree.getColumns();
int[] columnOrder = tree.getColumnOrder();
if( newLeft < 0 ) {
result = 0;
} else {
for( int i = 0; result == -1 && i < columns.length; i++ ) {
TreeColumn column = columns[ columnOrder [ i ] ];
int left = getLeft( column );
int width = column.getWidth();
if( isFixed( column ) ) {
left += getLeftOffset( column );
}
if( newLeft >= left && newLeft <= left + width ) {
result = i;
if( newLeft >= left + width / 2 && result < columns.length && !isFixed( column ) ) {
result++;
}
}
}
}
// Column was moved right of the right-most column
if( result == -1 ) {
result = columns.length;
}
return result;
}
private static boolean isFixed( TreeColumn column ) {
return getTreeAdapter( column ).isFixedColumn( column );
}
private static int getLeft( TreeColumn column ) {
return getTreeAdapter( column ).getColumnLeft( column );
}
private static ITreeAdapter getTreeAdapter( TreeColumn column ) {
return column.getParent().getAdapter( ITreeAdapter.class );
}
private static int getLeftOffset( TreeColumn column ) {
ITreeAdapter adapter = column.getParent().getAdapter( ITreeAdapter.class );
return adapter.getScrollLeft();
}
private static int arrayIndexOf( int[] array, int value ) {
int result = -1;
for( int i = 0; result == -1 && i < array.length; i++ ) {
if( array[ i ] == value ) {
result = i;
}
}
return result;
}
private static int[] arrayRemove( int[] array, int index ) {
int length = array.length;
int[] result = new int[ length - 1 ];
System.arraycopy( array, 0, result, 0, index );
if( index < length - 1 ) {
System.arraycopy( array, index + 1, result, index, length - index - 1 );
}
return result;
}
private static int[] arrayInsert( int[] array, int index, int value ) {
int length = array.length;
int[] result = new int[ length + 1 ];
System.arraycopy( array, 0, result, 0, length );
System.arraycopy( result, index, result, index + 1, length - index );
result[ index ] = value;
return result;
}
}