/*******************************************************************************
* Copyright (c) 2008 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.rwt.lifecycle.WidgetUtil;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
public class ViewToolBarManager extends ToolBarManager2 {
private static final String STYLING_VARIANT = "viewToolbar";
private ToolBar toolBar;
private ToolBar fakeToolbar;
public ToolBar createControl(Composite parent) {
if( !toolBarExist() && parent != null ) {
toolBar = new ToolBar( parent, SWT.NONE );
toolBar.setData( WidgetUtil.CUSTOM_VARIANT, STYLING_VARIANT );
toolBar.setMenu( getContextMenuControl() );
// create the fake Toolbar
fakeToolbar = new ToolBar( parent, SWT.NONE );
fakeToolbar.setVisible( false );
update( true );
}
return toolBar;
}
public ToolBar getControl() {
return toolBar;
}
private Menu getContextMenuControl() {
Menu result = null;
if( ( getContextMenuManager() != null ) && ( toolBar != null ) ) {
Menu menuWidget = getContextMenuManager().getMenu();
if( ( menuWidget == null ) || ( menuWidget.isDisposed() ) ) {
menuWidget = getContextMenuManager().createContextMenu( toolBar);
}
result = menuWidget;
}
return result;
}
private boolean toolBarExist() {
return toolBar != null && !toolBar.isDisposed();
}
/*
* (non-Javadoc) Method declared on IContributionManager.
*/
public void update( boolean force ) {
if( isDirty() || force ) {
if( toolBarExist() ) {
// clean contains all active items without separators
IContributionItem[] items = getItems();
ArrayList clean = new ArrayList( items.length );
for( int i = 0; i < items.length; ++i ) {
IContributionItem ci = items[ i ];
if( !ci.isSeparator() ) {
clean.add( ci );
}
}
// determine obsolete items (removed or non active)
ToolItem[] mi = toolBar.getItems();
ArrayList toRemove = new ArrayList();
for( int i = 0; i < mi.length; i++ ) {
toRemove.add( mi[ i ] );
}
// add fake toolbar items to the items to remove
for( int i = 0; i < fakeToolbar.getItemCount(); i++ ) {
toRemove.add( fakeToolbar.getItem( 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;
}
// fill item if visible, if not fill it into the fake toolbar
ToolBar tempToolBar = null;
if( src.isVisible() ) {
src.fill( toolBar, destIx );
tempToolBar = toolBar;
} else {
src.fill( fakeToolbar, destIx );
tempToolBar = fakeToolbar;
}
// check necessary for bug 306741
if( destIx >= 0 && destIx < tempToolBar.getItemCount() - 1 ) {
ToolItem toolItem = tempToolBar.getItem( destIx );
toolItem.setData( src );
toolItem.setData( WidgetUtil.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 );
} finally {
// turn redraw back on if we turned it off above
if( useRedraw ) {
toolBar.setRedraw( true );
}
}
}
}
}
public List getToolItems() {
List result = new ArrayList();
for( int i = 0; i < toolBar.getItemCount(); i++ ) {
result.add( toolBar.getItem( i ) );
}
for( int i = 0; i < fakeToolbar.getItemCount(); i++ ) {
result.add( fakeToolbar.getItem( i ) );
}
return result;
}
}