/******************************************************************************* * Copyright (c) 2009, 2014 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.builder; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.rap.internal.design.example.ILayoutSetConstants; import org.eclipse.rap.internal.design.example.Messages; import org.eclipse.rap.rwt.RWT; import org.eclipse.rap.ui.interactiondesign.layout.ElementBuilder; import org.eclipse.rap.ui.internal.preferences.SessionScope; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.internal.graphics.Graphics; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.ui.IPerspectiveDescriptor; import org.eclipse.ui.IPerspectiveRegistry; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PerspectiveAdapter; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.WorkbenchException; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; import org.osgi.service.prefs.BackingStoreException; import org.osgi.service.prefs.Preferences; public class PerspectiveSwitcherBuilder extends ElementBuilder { private static final String RAP_PERSPECTIVES = "RAP_PERSPECTIVES"; //$NON-NLS-1$ private final Composite background; private final Map perspectiveButtonMap; private final Map buttonPerspectiveMap; private final List buttonList; private final List perspectiveList; private Button otherButton; private final Image left; private final Image right; private final Image bg; private final Image bgActive; private final PerspectiveAdapter perspectiveAdapter = new PerspectiveAdapter() { @Override public void perspectiveActivated( IWorkbenchPage page, IPerspectiveDescriptor perspective ) { addIdToStore( perspective.getId() ); Button button = createPerspectiveButton( perspective ); cleanButtons( button ); background.layout( true ); Control[] children = { background }; Composite parent = getParent(); parent.changed( children ); parent.layout( true ); parent.getParent().layout( true ); } }; public PerspectiveSwitcherBuilder( Composite parent, String subSetId ) { super( parent, subSetId ); background = new Composite( parent, SWT.NONE ); background.setData( RWT.CUSTOM_VARIANT, "compTrans" ); //$NON-NLS-1$ RowLayout layout = new RowLayout(); background.setLayout( layout ); layout.spacing = 3; layout.marginBottom = 0; layout.marginTop = 0; perspectiveButtonMap = new HashMap(); buttonPerspectiveMap = new HashMap(); buttonList = new ArrayList(); perspectiveList = new ArrayList(); // images left = getImage( ILayoutSetConstants.PERSP_LEFT_ACTIVE ); right = getImage( ILayoutSetConstants.PERSP_RIGHT_ACTIVE ); bg = getImage( ILayoutSetConstants.PERSP_BG ); bgActive = getImage( ILayoutSetConstants.PERSP_BG_ACTIVE ); } @Override public void addControl( Control control, Object layoutData ) { } @Override public void addControl( Control control, String positionId ) { } private void addIdToStore( String id ) { if( !perspectiveList.contains( id ) ) { perspectiveList.add( id ); } save(); } @Override public void addImage( Image image, Object layoutData ) { } @Override public void addImage( Image image, String positionId ) { } @Override public void build() { IWorkbench workbench = PlatformUI.getWorkbench(); IWorkbenchWindow workbenchWindow = workbench.getActiveWorkbenchWindow(); workbenchWindow.addPerspectiveListener( perspectiveAdapter ); IPerspectiveDescriptor[] descriptors = load(); for( int i = 0; i < descriptors.length; i++ ) { createPerspectiveButton( descriptors[ i ] ); } // Button for the perspective dialog Composite otherBg = new Composite( background, SWT.NONE ); otherBg.setLayout( new FormLayout() ); otherButton = new Button( otherBg, SWT.PUSH | SWT.FLAT ); FormData fdOther = new FormData(); otherButton.setLayoutData( fdOther ); fdOther.left = new FormAttachment( 0, left.getBounds().width ); FormData buttonPos = getLayoutSet().getPosition( ILayoutSetConstants.PERSP_BUTTON_POS ); fdOther.top = buttonPos.top; otherButton.setData( RWT.CUSTOM_VARIANT, "perspective" ); //$NON-NLS-1$ otherButton.setText( Messages.get().PerspectiveSwitcherBuilder_Other ); IWorkbenchWindow activeWindow = workbench.getActiveWorkbenchWindow(); final IWorkbenchAction perspectiveAction = ActionFactory.OPEN_PERSPECTIVE_DIALOG.create( activeWindow ); otherButton.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent e ) { perspectiveAction.run(); } } ); } /* * redesign the buttons */ private void cleanButtons( Button current ) { for( int i = 0; i < buttonList.size(); i++ ) { Button button = ( Button ) buttonList.get( i ); Composite parent = button.getParent(); Control[] children = parent.getChildren(); if( !button.equals( current ) ) { for( int j = 0; j < children.length; j++ ) { if( children[ j ] instanceof Label ) { children[ j ].setVisible( false ); } } parent.setBackgroundImage( bg ); button.setData( RWT.CUSTOM_VARIANT, "perspective" ); //$NON-NLS-1$ } else { for( int j = 0; j < children.length; j++ ) { children[ j ].setVisible( true ); } parent.setBackgroundImage( bgActive ); button.setData( RWT.CUSTOM_VARIANT, "perspectiveActive" ); //$NON-NLS-1$ } parent.layout( true ); } } private void cleanUpButton( IPerspectiveDescriptor perspective, Button button ) { buttonList.remove( button ); perspectiveButtonMap.remove( perspective ); buttonPerspectiveMap.remove( button ); button.getParent().dispose(); background.layout( true ); Control[] children = { background }; Composite parent = getParent(); parent.changed( children ); parent.layout( true ); parent.getParent().layout( true ); } private void closePerspective( IPerspectiveDescriptor desc ) { IWorkbench workbench = PlatformUI.getWorkbench(); IWorkbenchWindow workbenchWindow = workbench.getActiveWorkbenchWindow(); IWorkbenchPage activePage = workbenchWindow.getActivePage(); activePage.closePerspective( desc, true, false ); } private Button createPerspectiveButton( final IPerspectiveDescriptor desc ) { Button result = ( Button ) perspectiveButtonMap.get( desc ); if( result == null && desc != null && desc.getLabel() != null ) { Composite buttonBg = new Composite( background, SWT.NONE ); buttonBg.setBackground( Graphics.getColor( 247, 247, 247 ) ); buttonBg.setLayout( new FormLayout() ); Label leftBg = new Label( buttonBg, SWT.NONE ); leftBg.setImage( left ); FormData fdLeftBg = new FormData(); leftBg.setLayoutData( fdLeftBg ); fdLeftBg.top = new FormAttachment( 0 ); fdLeftBg.left = new FormAttachment( 0 ); fdLeftBg.height = left.getBounds().height; fdLeftBg.width = left.getBounds().width; Label rightBg = new Label( buttonBg, SWT.NONE ); rightBg.setImage( right ); FormData fdRightBg = new FormData(); rightBg.setLayoutData( fdRightBg ); fdRightBg.top = new FormAttachment( 0 ); fdRightBg.height = right.getBounds().height; fdRightBg.width = right.getBounds().width; final Button perspButton = new Button( buttonBg, SWT.PUSH | SWT.FLAT ); perspButton.setData( RWT.CUSTOM_VARIANT, "perspective" ); //$NON-NLS-1$ FormData fdButton = new FormData(); perspButton.setLayoutData( fdButton ); fdButton.left = new FormAttachment( leftBg ); FormData buttonPos = getLayoutSet().getPosition( ILayoutSetConstants.PERSP_BUTTON_POS ); fdButton.top = buttonPos.top; fdRightBg.left = new FormAttachment( perspButton ); perspButton.setText( desc.getLabel() ); perspectiveButtonMap.put( desc, perspButton ); buttonPerspectiveMap.put( perspButton, desc ); buttonList.add( perspButton ); perspButton.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent e ) { cleanButtons( perspButton ); switchPerspective( desc.getId() ); } } ); Menu menu = new Menu( perspButton ); MenuItem item = new MenuItem( menu, SWT.PUSH ); item.setText( Messages.get().PerspectiveSwitcherBuilder_Close ); item.setImage( getImage( ILayoutSetConstants.PERSP_CLOSE ) ); item.addSelectionListener( new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent e ) { removeIdFromStore( desc.getId() ); Button button = ( Button ) perspectiveButtonMap.get( desc); if( button != null ) { cleanUpButton( desc, button ); } closePerspective( desc ); background.layout(); } } ); perspButton.setMenu( menu ); if( otherButton != null ) { otherButton.getParent().moveBelow( perspButton.getParent() ); } result = perspButton; } return result; } private IEclipsePreferences createSessionScope() { return new SessionScope().getNode( RAP_PERSPECTIVES ); } @Override public void dispose() { IWorkbench workbench = PlatformUI.getWorkbench(); IWorkbenchWindow workbenchWindow = workbench.getActiveWorkbenchWindow(); workbenchWindow.removePerspectiveListener( perspectiveAdapter ); Composite parent = getParent(); if( parent != null && !parent.isDisposed() ) { parent.dispose(); } } @Override public Control getControl() { return background; } @Override public Point getSize() { return null; } private IPerspectiveDescriptor[] load() { Preferences store = createSessionScope(); String[] keys; IPerspectiveDescriptor[] result = null; IWorkbench workbench = PlatformUI.getWorkbench(); IPerspectiveRegistry registry = workbench.getPerspectiveRegistry(); try { keys = store.keys(); result = new IPerspectiveDescriptor[ keys.length ]; for( int i = 0; i < keys.length; i++ ) { String perspectiveId = keys[ i ]; int pos = store.getInt( perspectiveId, 0 ); if( pos <= perspectiveList.size() ) { perspectiveList.add( pos, perspectiveId ); } else { perspectiveList.add( perspectiveId ); } } for( int i = 0; i < perspectiveList.size(); i++ ) { String id = ( String ) perspectiveList.get( i ); result[ i ] = registry.findPerspectiveWithId( id ); } } catch( BackingStoreException e ) { e.printStackTrace(); } return result; } private void removeIdFromStore( String id ) { perspectiveList.remove( id ); Preferences store = createSessionScope(); store.remove( id ); save(); } private void save() { Preferences store = createSessionScope(); try { store.clear(); for( int i = 0; i < perspectiveList.size(); i++ ) { String id = ( String ) perspectiveList.get( i ); store.putInt( id, i ); } store.flush(); } catch( BackingStoreException e ) { e.printStackTrace(); } } private void switchPerspective( String perspectiveId) { IWorkbench workbench = PlatformUI.getWorkbench(); IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); try { workbench.showPerspective( perspectiveId, window ); } catch( WorkbenchException e ) { e.printStackTrace(); } } }