blob: f7891a2e127eb68fd3844d19496491c16888ec13 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2009 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.rap.examples.internal;
import java.util.Arrays;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.viewers.*;
import org.eclipse.rap.examples.internal.model.ExampleCategory;
import org.eclipse.rap.examples.internal.model.ExamplesModel;
import org.eclipse.rwt.*;
import org.eclipse.rwt.events.BrowserHistoryEvent;
import org.eclipse.rwt.events.BrowserHistoryListener;
import org.eclipse.rwt.lifecycle.WidgetUtil;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.part.ViewPart;
public class NavigationView extends ViewPart {
public static final String ID
= "org.eclipse.rap.examples.navigationView";
private ExpandBar expandBar;
private String selectedElement;
private final SelectionListener listSelectionListener;
private final SelectionProvider selectionProvider;
public NavigationView() {
listSelectionListener = new ListSelectionListener();
selectionProvider = new SelectionProvider();
}
public void createPartControl( final Composite parent ) {
parent.setLayout( new FillLayout() );
createExpandBar( parent );
fillExpandBar( ExamplesModel.getInstance() );
getSite().setSelectionProvider( selectionProvider );
initBrowserHistorySupport();
initSelection();
getSite().getShell().getDisplay().asyncExec( new Runnable() {
public void run() {
getSite().getPage().activate( NavigationView.this );
}
} );
}
public void setFocus() {
expandBar.setFocus();
}
private void createExpandBar( final Composite parent ) {
expandBar = new ExpandBar( parent, SWT.V_SCROLL );
expandBar.setSpacing( 2 );
// TODO [rst] Auto-collapse mechanism, enable when there are more items
// expandBar.addExpandListener( new ExpandListener() {
//
// public void itemCollapsed( final ExpandEvent e ) {
// ExpandItem item = ( ExpandItem )e.item;
// List list = ( List )item.getControl();
// list.deselectAll();
// }
//
// public void itemExpanded( final ExpandEvent e ) {
// ExpandItem[] items = expandBar.getItems();
// for( int i = 0; i < items.length; i++ ) {
// ExpandItem item = items[ i ];
// if( item != e.item ) {
// item.setExpanded( false );
// List list = ( List )item.getControl();
// list.deselectAll();
// }
// }
// }
// } );
// workaround to apply TextSizeDetermination results
parent.addControlListener( new ControlAdapter() {
public void controlResized( final ControlEvent e ) {
ExpandItem[] items = expandBar.getItems();
for( int i = 0; i < items.length; i++ ) {
ExpandItem item = items[ i ];
List list = ( List )item.getControl();
item.setHeight( list.computeSize( SWT.DEFAULT, SWT.DEFAULT ).y );
}
}
} );
}
private void fillExpandBar( final ExamplesModel model ) {
ExampleCategory[] categories = model.getCategories();
Arrays.sort( categories );
for( int i = 0; i < categories.length; i++ ) {
ExampleCategory category = categories[ i ];
ExpandItem item = createCategoryItem( category );
List list = ( List )item.getControl();
list.setItems( model.getExamplesInCategory( category ) );
item.setHeight( list.computeSize( SWT.DEFAULT, SWT.DEFAULT ).y );
}
}
private ExpandItem createCategoryItem( final ExampleCategory category ) {
ExpandItem item = new ExpandItem( expandBar, SWT.NONE );
item.setText( category.getName() );
List list = new List( expandBar, SWT.SINGLE );
list.setData( WidgetUtil.CUSTOM_VARIANT, "EXAMPLES" );
list.addSelectionListener( listSelectionListener );
item.setControl( list );
// TODO [rst] Remove this block when auto-collapse is activated again
// ----
item.setExpanded( true );
// ----
return item;
}
private void deselectAll( final List skipped ) {
ExpandItem[] items = expandBar.getItems();
for( int i = 0; i < items.length; i++ ) {
ExpandItem item = items[ i ];
List list = ( List )item.getControl();
if( list != skipped ) {
list.deselectAll();
}
}
}
private void initBrowserHistorySupport() {
IBrowserHistory history = RWT.getBrowserHistory();
history.addBrowserHistoryListener( new BrowserHistoryListener() {
public void navigated( final BrowserHistoryEvent event ) {
deselectAll( null );
setSelection( event.entryId, true, false );
}
} );
}
private void initSelection() {
if( expandBar.getItemCount() > 0 ) {
ExpandItem firstItem = expandBar.getItem( 0 );
firstItem.setExpanded( true );
List list = ( List )firstItem.getControl();
list.setSelection( 0 );
setSelection( list.getItem( 0 ), false, true );
}
}
private void setSelection( final String newSelection,
final boolean updateControl,
final boolean updateHistory )
{
boolean changed;
if( selectedElement == null ) {
changed = newSelection != null;
} else {
changed = !selectedElement.equals( newSelection );
}
if( changed ) {
selectedElement = newSelection;
// keep in sync with branding
if( updateHistory ) {
String text = "RAP Examples - " + selectedElement;
RWT.getBrowserHistory().createEntry( selectedElement, text );
}
selectionProvider.fireSelectionChanged();
}
if( updateControl ) {
ExpandItem[] expandItems = expandBar.getItems();
boolean done = false;
for( int i = 0; !done && i < expandItems.length; i++ ) {
ExpandItem expandItem = expandItems[ i ];
List list = ( List )expandItem.getControl();
String[] listItems = list.getItems();
int index = indexOf( listItems, newSelection );
if( index != -1 ) {
done = true;
list.setSelection( index );
expandItems[ i ].setExpanded( true );
list.setFocus();
}
}
}
}
private static int indexOf( final String[] strings, final String string ) {
int result = -1;
for( int i = 0; result == -1 && i < strings.length; i++ ) {
if( string.equals( strings[ i ] ) ) {
result = i;
}
}
return result;
}
private final class ListSelectionListener extends SelectionAdapter {
public void widgetSelected( final SelectionEvent event ) {
List list = ( List )event.widget;
int index = list.getSelectionIndex();
deselectAll( list );
setSelection( index == -1 ? null : list.getItem( index ), false, true );
}
}
private final class SelectionProvider implements ISelectionProvider {
private final ListenerList selectionChangedListeners = new ListenerList();
public void addSelectionChangedListener(
final ISelectionChangedListener lsnr )
{
selectionChangedListeners.add( lsnr );
}
public void removeSelectionChangedListener(
final ISelectionChangedListener lsnr )
{
selectionChangedListeners.remove( lsnr );
}
public ISelection getSelection() {
ISelection result;
if( selectedElement == null ) {
result = StructuredSelection.EMPTY;
} else {
result = new StructuredSelection( selectedElement );
}
return result;
}
public void setSelection( final ISelection selection ) {
throw new UnsupportedOperationException();
}
void fireSelectionChanged() {
ISelection selection = getSelection();
final SelectionChangedEvent event
= new SelectionChangedEvent( this, selection );
Object[] listeners = selectionChangedListeners.getListeners();
for( int i = 0; i < listeners.length; ++i ) {
final ISelectionChangedListener listener
= ( ISelectionChangedListener )listeners[ i ];
SafeRunnable.run( new SafeRunnable() {
public void run() {
listener.selectionChanged( event );
}
} );
}
}
}
}