/*******************************************************************************
* Copyright (c) 2012, 2016 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 com.eclipsesource.tabris.widgets.enhancement;
import static com.eclipsesource.tabris.internal.Clauses.when;
import static com.eclipsesource.tabris.internal.Clauses.whenNull;
import static com.eclipsesource.tabris.internal.DataWhitelist.WhiteListEntry.ALT_SELECTION;
import static com.eclipsesource.tabris.internal.DataWhitelist.WhiteListEntry.BACK_FOCUS;
import static com.eclipsesource.tabris.internal.DataWhitelist.WhiteListEntry.REFRESH_HANDLER;
import static com.eclipsesource.tabris.internal.WidgetsUtil.setData;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.rap.rwt.template.Cell;
import org.eclipse.rap.rwt.template.Template;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.internal.widgets.IDisplayAdapter;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
/**
* @since 0.8
*/
@SuppressWarnings("restriction")
public class TreeDecorator extends WidgetDecorator<TreeDecorator> {
public enum TreePart {
LEAF, BRANCH, ALL
}
private final Tree tree;
TreeDecorator( Tree tree ) {
super( tree );
this.tree = tree;
}
/**
* <p>
* Defines a title for a tree. This is comparable with a header for a tree.
* </p>
*
* @since 0.9
*/
public TreeDecorator useTitle( String title ) {
tree.setToolTipText( title );
return this;
}
/**
* <p>
* This enables alternative selection on tree items. When the alternative action will be selected the
* {@link SelectionEvent#stateMask} contains the {@link SWT#ALT} key.
* </p>
*
* @since 0.9
*/
public TreeDecorator enableAlternativeSelection( TreePart part ) {
switch( part ) {
case LEAF:
setData( tree, ALT_SELECTION, "leaf" );
break;
case BRANCH:
setData( tree, ALT_SELECTION, "branch" );
break;
case ALL:
setData( tree, ALT_SELECTION, "all" );
break;
}
return this;
}
/**
* <p>
* Enables the defined tree to take advantage of the back button. This means when the back button will be pressed
* the tree navigates back.
* </p>
*
* @since 0.10
* @deprecated use {@link TreeDecorator#setBackButtonNavigationEnabled(boolean)}
*/
@Deprecated
public TreeDecorator enableBackButtonNavigation() {
return setBackButtonNavigationEnabled( true );
}
/**
* <p>
* Enables or disables the defined tree to take advantage of the back button. This means when the back button will
* be pressed the tree navigates back.
* </p>
*
* @since 1.3
*/
public TreeDecorator setBackButtonNavigationEnabled( boolean enabled ) {
setData( tree, BACK_FOCUS, Boolean.valueOf( enabled ) );
if( enabled ) {
setDataToNullOnOtherTrees();
}
return this;
}
private void setDataToNullOnOtherTrees() {
IDisplayAdapter displayAdapter = tree.getDisplay().getAdapter( IDisplayAdapter.class );
for( Shell shell : displayAdapter.getShells() ) {
visitAllTrees( shell );
}
}
private void visitAllTrees( Composite root ) {
Control[] children = root.getChildren();
for( Control control : children ) {
if( control instanceof Tree && control != tree ) {
removeBackFocusData( control );
} else if( control instanceof Composite ) {
visitAllTrees( ( Composite )control );
}
}
}
private void removeBackFocusData( Control control ) {
Object data = control.getData( BACK_FOCUS.getKey() );
if( data != null && data.equals( Boolean.TRUE ) ) {
setData( control, BACK_FOCUS, null );
}
}
/**
* <p>
* Controls the number of preloaded items outside (above and below) visible area of a virtual
* <code>Tree</code>.
* </p>
*
* @param preloadedItems the items to preload. Must be > 0.
*
* @since 1.2
*/
public TreeDecorator setPreloadedItems( int preloadedItems ) {
when( preloadedItems < 0 ).throwIllegalArgument( "Preloaded items must be > 0 but was " + preloadedItems );
tree.setData( RWT.PRELOADED_ITEMS, Integer.valueOf( preloadedItems ) );
return this;
}
/**
* <p>
* Sets a {@link Template} on this tree.
* </P>
*
* @param template the template to use. Must not be null.
*
* @see Template
* @see Cell
* @see RWT#ROW_TEMPLATE
*
* @since 1.2
*/
public TreeDecorator setTemplate( Template template ) {
whenNull( template ).throwIllegalArgument( "Template must not be null" );
tree.setData( RWT.ROW_TEMPLATE, template );
return this;
}
/**
* <p>
* Set the item height of a {@link TreeItem} in pixels.
* </p>
*
* @param itemHeight the item height in pixels. Must be >= 0.
*
* @since 1.2
*/
public TreeDecorator setItemHeight( int itemHeight ) {
when( itemHeight < 0 ).throwIllegalArgument( "ItemHeight must be >= 0 but was " + itemHeight );
tree.setData( RWT.CUSTOM_ITEM_HEIGHT, Integer.valueOf( itemHeight ) );
return this;
}
/**
* <p>
* Sets a {@link RefreshHandler} to a {@link Tree}. This instructs a client to add native refresh capabilities to
* the {@link Tree}.
* </p>
*
* @see RefreshHandler
*
* @param handler the {@link RefreshHandler} to add. Must not be <code>null</code>.
*
* @since 1.4
*/
public TreeDecorator setRefreshHandler( RefreshHandler handler ) {
whenNull( handler ).throwIllegalArgument( "RefreshHandler must not be null" );
setData( tree, REFRESH_HANDLER, handler.getId() );
handler.hookToWidget( tree );
return this;
}
}