/******************************************************************************* * Copyright (c) 2008, 2012 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.internal.design.example.managers; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.jface.action.IContributionItem; import org.eclipse.jface.internal.provisional.action.ToolBarManager2; import org.eclipse.rap.rwt.RWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolItem; public class ViewToolBarManager extends ToolBarManager2 { private static final String STYLING_VARIANT = "viewToolbar"; //$NON-NLS-1$ private ItemData[] itemsData; @Override public ToolBar createControl( final Composite parent ) { ToolBar toolBar = getControl(); if( !toolBarExist() && parent != null ) { toolBar = super.createControl( parent ); toolBar.setData( RWT.CUSTOM_VARIANT, STYLING_VARIANT ); } return toolBar; } @Override public void update( final boolean force ) { if( isDirty() || force ) { if( toolBarExist() ) { ToolBar toolBar = getControl(); // clean contains all active items without double separators IContributionItem[] items = getItems(); ArrayList clean = new ArrayList(items.length); IContributionItem separator = null; for( int i = 0; i < items.length; ++i ) { IContributionItem ci = items[ i ]; if( ci.isSeparator() ) { separator = ci; } else { if( separator != null ) { if( clean.size() > 0 ) { clean.add( separator ); } separator = null; } clean.add( ci ); } } // determine obsolete items (removed or non active) ToolItem[] mi = toolBar.getItems(); ArrayList toRemove = new ArrayList( mi.length ); for( int i = 0; i < mi.length; i++ ) { // there may be null items in a toolbar if( mi[ i ] == null ) { continue; } Object data = mi[ i ].getData(); if( data == null || !clean.contains( data ) || ( data instanceof IContributionItem && ( ( IContributionItem ) data) .isDynamic() ) ) { toRemove.add( mi[ i ] ); } } // Turn redraw off if the number of items to be added // is above a certain threshold, to minimize flicker, // otherwise the toolbar can be seen to redraw after each item. // Do this before any modifications are made. // We assume each contribution item will contribute at least one // toolbar item. boolean useRedraw = clean.size() - ( mi.length - toRemove.size() ) >= 3; try { if( useRedraw ) { toolBar.setRedraw( false ); } // remove obsolete items for (int i = toRemove.size(); --i >= 0;) { ToolItem item = ( ToolItem )toRemove.get( i ); if( !item.isDisposed() ) { Control ctrl = item.getControl(); if( ctrl != null ) { item.setControl( null ); ctrl.dispose(); } item.dispose(); } } // add new items IContributionItem src, dest; mi = toolBar.getItems(); int srcIx = 0; int destIx = 0; for( Iterator e = clean.iterator(); e.hasNext(); ) { src = ( IContributionItem )e.next(); // get corresponding item in SWT widget if( srcIx < mi.length ) { dest = ( IContributionItem )mi[ srcIx ].getData(); } else { dest = null; } if( dest != null && src.equals( dest ) ) { srcIx++; destIx++; continue; } if( dest != null && dest.isSeparator() && src.isSeparator() ) { mi[ srcIx ].setData( src ); srcIx++; destIx++; continue; } int start = toolBar.getItemCount(); src.fill( toolBar, destIx ); int newItems = toolBar.getItemCount() - start; for( int i = 0; i < newItems; i++ ) { ToolItem item = toolBar.getItem( destIx++ ); item.setData( src ); item.setData( RWT.CUSTOM_VARIANT, STYLING_VARIANT ); } } // remove any old tool items not accounted for for( int i = mi.length; --i >= srcIx; ) { ToolItem item = mi[ i ]; if( !item.isDisposed() ) { Control ctrl = item.getControl(); if( ctrl != null ) { item.setControl( null ); ctrl.dispose(); } item.dispose(); } } setDirty(false); updateItemsData(); disposeInvisibleItems(); } finally { // turn redraw back on if we turned it off above if( useRedraw ) { toolBar.setRedraw( true ); } } } } } public ItemData[] getItemsData() { return itemsData; } private boolean toolBarExist() { ToolBar toolBar = getControl(); return toolBar != null && !toolBar.isDisposed(); } private void updateItemsData() { ToolBar toolBar = getControl(); ToolItem[] items = toolBar.getItems(); List<ItemData> data = new ArrayList<ItemData>(); for( int i = 0; i < items.length; i++ ) { IContributionItem contributionItem = ( IContributionItem )items[ i ].getData(); if( !contributionItem.isGroupMarker() && !contributionItem.isSeparator() ) { ItemData itemData = new ItemData( contributionItem.getId(), items[ i ].getText(), items[ i ].getToolTipText(), items[ i ].getImage() ); data.add( itemData ); } } itemsData = data.toArray( new ItemData[ 0 ] ); } private void disposeInvisibleItems() { ToolBar toolBar = getControl(); ToolItem[] items = toolBar.getItems(); for( int i = 0; i < items.length; i++ ) { ToolItem item = items[ i ]; if( !item.isDisposed() ) { Object data = item.getData(); if( data instanceof IContributionItem ) { IContributionItem itemData = ( IContributionItem )data; if( !itemData.isVisible() ) { Control ctrl = item.getControl(); if( ctrl != null ) { item.setControl( null ); ctrl.dispose(); } item.dispose(); } } } } } }