/******************************************************************************* * <copyright> * * Copyright (c) 2011, 2011 SAP AG. * 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: * Bug 336488 - DiagramEditor API * pjpaulin - Bug 352120 - Now uses IDiagramContainerUI interface * * </copyright> * *******************************************************************************/ package org.eclipse.graphiti.ui.editor; import org.eclipse.gef.KeyHandler; import org.eclipse.gef.Tool; import org.eclipse.gef.dnd.TemplateTransferDragSourceListener; import org.eclipse.gef.palette.PaletteRoot; import org.eclipse.gef.tools.ConnectionCreationTool; import org.eclipse.gef.tools.CreationTool; import org.eclipse.gef.ui.palette.DefaultPaletteViewerPreferences; import org.eclipse.gef.ui.palette.FlyoutPaletteComposite; import org.eclipse.gef.ui.palette.FlyoutPaletteComposite.FlyoutPreferences; import org.eclipse.gef.ui.palette.PaletteViewer; import org.eclipse.gef.ui.palette.PaletteViewerPreferences; import org.eclipse.gef.ui.palette.PaletteViewerProvider; import org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette; import org.eclipse.graphiti.ui.internal.GraphitiUIPlugin; import org.eclipse.graphiti.ui.internal.editor.GFPaletteRoot; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyEvent; /** * This class can be subclassed by clients to adapt the palette appearance and * behavior of the Graphiti diagram Editor. The API is very much aligned with * the way GEF handles the palette within its editors, see * {@link GraphicalEditorWithFlyoutPalette} for more information on that. To * exchange the default implementation you have to return an instance of your * subclass in the method {@link DiagramBehavior#createPaletteBehaviour()}.<br> * Note that there is always a 1:1 relation with a {@link DiagramBehavior}. * * @since 0.9 */ public class DefaultPaletteBehavior { /** * Property name for storing the location (east, west) of the palette within * the editor in an Eclipse preference store. */ protected static final String PROPERTY_PALETTE_DOCK_LOCATION = "Dock location"; //$NON-NLS-1$ /** * Property name for storing the size of the palette within the editor in an * Eclipse preference store. */ protected static final String PROPERTY_PALETTE_SIZE = "Palette Size"; //$NON-NLS-1$ /** * Property name for storing the state (collapsed, expanded, hidden) of the * palette within the editor in an Eclipse preference store. */ protected static final String PROPERTY_PALETTE_STATE = "Palette state"; //$NON-NLS-1$ /** * The initial size of the palette. */ protected static final int DEFAULT_PALETTE_SIZE = 130; /** * The associated {@link DiagramBehavior} * * @since 0.10 */ protected final DiagramBehavior diagramBehavior; private PaletteRoot paletteRoot; /** * Creates a new standard palette behaviour for a Graphiti diagram editor. * The passed {@link DiagramBehavior} is closely linked to this instance (1:1 * relation) and both instances will have a common lifecycle. * * @param diagramEditor * The associated {@link DiagramBehavior}. * @since 0.10 */ public DefaultPaletteBehavior(DiagramBehavior diagramBehavior) { super(); this.diagramBehavior = diagramBehavior; } /** * Creates the {@link PaletteRoot} of this editor. To retrieve the * {@link PaletteRoot} object use {@link #getPaletteRoot()} instead which * will return an already existing instance or create a new one by * delegating to this method. * * @return a new Graphiti specific {@link PaletteRoot} instance * @see org.eclipse.graphiti.ui.editor.GraphicalEditorIncludingPalette#getPaletteRoot() */ protected PaletteRoot createPaletteRoot() { return new GFPaletteRoot(diagramBehavior.getDiagramTypeProvider()); } /** * Returns the already existing {@link PaletteRoot} instance for the * {@link DiagramBehavior} associated the this palette behavior or creates a * new {@link PaletteRoot} instance in case none exists. * * @return a new Graphiti specific {@link PaletteRoot} instance */ public PaletteRoot getPaletteRoot() { if (paletteRoot == null) { paletteRoot = createPaletteRoot(); } return paletteRoot; } /** * Initializes the used GEF palette viewer to display the palette as * defined. The default implementation initializes the preference store with * the GEF {@link DefaultPaletteViewerPreferences} and triggers a refresh of * the palette. */ public void initializeViewer() { // Set preference-store for palette PaletteViewer paletteViewer = diagramBehavior.getEditDomain().getPaletteViewer(); if (paletteViewer != null) { IPreferenceStore store = GraphitiUIPlugin.getDefault().getPreferenceStore(); paletteViewer.setPaletteViewerPreferences(new DefaultPaletteViewerPreferences(store)); // Refresh the PaletteViewer // This can be achieved by firing a font-change-event from the // IPreferenceStore. It would be nicer, if the PaletteViewer would // have some kind of refresh()-method directly. store.firePropertyChangeEvent(PaletteViewerPreferences.PREFERENCE_FONT, null, null); } } /** * Returns the Graphiti specific preferences for the palette. This method * will be called by the GEF {@link GraphicalEditorWithFlyoutPalette} during * initialization. * * @return a Graphiti specific instanceof {@link FlyoutPreferences}. */ public FlyoutPreferences getPalettePreferences() { return new FlyoutPreferences() { public int getDockLocation() { return getPreferenceStore().getInt(PROPERTY_PALETTE_DOCK_LOCATION); } public int getPaletteState() { // TODO ? Move isShowFlyoutPalette from TBP to // DefaultPaletteBehaviour? if (!diagramBehavior.getDiagramTypeProvider().getCurrentToolBehaviorProvider().isShowFlyoutPalette()) { return 8; // FlyoutPaletteComposite.STATE_HIDDEN is private } return getPreferenceStore().getInt(PROPERTY_PALETTE_STATE); } public int getPaletteWidth() { return getPreferenceStore().getInt(PROPERTY_PALETTE_SIZE); } public void setDockLocation(int location) { getPreferenceStore().setValue(PROPERTY_PALETTE_DOCK_LOCATION, location); } public void setPaletteState(int state) { getPreferenceStore().setValue(PROPERTY_PALETTE_STATE, state); } public void setPaletteWidth(int width) { getPreferenceStore().setValue(PROPERTY_PALETTE_SIZE, width); } }; } /** * Returns the PaletteViewerProvider, which can be used to create a new * PaletteViewer. This method can be overwritten to return a subclass of the * PaletteViewerProvider, which configures the PaletteViewer with a * different ContextMenu, with a PaletteCustomizer or with a different * IPreferencesStore. Do not call this method directly, instead call * getPaletteViewerProvider(), which buffers the created object. * <p> * By default this method returns a new PaletteViewerProvider. * * @return The PaletteViewerProvider, which can be used to create a new * PaletteViewer. */ protected PaletteViewerProvider createPaletteViewerProvider() { return new PaletteViewerProvider(diagramBehavior.getEditDomain()) { private KeyHandler paletteKeyHandler = null; protected void configurePaletteViewer(PaletteViewer viewer) { super.configurePaletteViewer(viewer); viewer.getKeyHandler().setParent(getPaletteKeyHandler()); viewer.addDragSourceListener(new TemplateTransferDragSourceListener(viewer)); } /** * @return Palette Key Handler for the palette */ private KeyHandler getPaletteKeyHandler() { if (paletteKeyHandler == null) { paletteKeyHandler = new KeyHandler() { /** * Processes a <i>key released </i> event. This method * is called by the Tool whenever a key is released, and * the Tool is in the proper state. Overridden to * support pressing the enter key to create a shape or * connection (between two selected shapes) * * @param event * the KeyEvent * @return <code>true</code> if KeyEvent was handled in * some way */ public boolean keyReleased(KeyEvent event) { if (event.keyCode == SWT.Selection) { Tool tool = getEditDomain().getPaletteViewer().getActiveTool().createTool(); if (tool instanceof CreationTool || tool instanceof ConnectionCreationTool) { tool.keyUp(event, diagramBehavior.getDiagramContainer().getGraphicalViewer()); // Deactivate current selection getEditDomain().getPaletteViewer().setActiveTool(null); return true; } } return super.keyReleased(event); } }; } return paletteKeyHandler; } }; } /** * Refreshes the palette. */ public void refreshPalette() { PaletteRoot pr = getPaletteRoot(); if (pr instanceof GFPaletteRoot) { GFPaletteRoot gpr = (GFPaletteRoot) pr; gpr.updatePaletteEntries(); } } /** * Disposes this instance. Must be called before closing the associated * Graphiti diagram editor. The default implementation clears the * {@link #paletteRoot} reference. */ public void dispose() { paletteRoot = null; } private IPreferenceStore getPreferenceStore() { IPreferenceStore ps = GraphitiUIPlugin.getDefault().getPreferenceStore(); ps.setDefault(DefaultPaletteBehavior.PROPERTY_PALETTE_STATE, FlyoutPaletteComposite.STATE_PINNED_OPEN); ps.setDefault(DefaultPaletteBehavior.PROPERTY_PALETTE_SIZE, DEFAULT_PALETTE_SIZE); return ps; } }