/****************************************************************************** * Copyright (c) 2005, 2007 IBM Corporation 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: * IBM Corporation - initial API and implementation ****************************************************************************/ package org.eclipse.gmf.runtime.diagram.ui.editpolicies; import java.util.Iterator; import java.util.List; import org.eclipse.gef.GraphicalEditPart; import org.eclipse.gef.Tool; import org.eclipse.gef.palette.PaletteContainer; import org.eclipse.gef.palette.PaletteDrawer; import org.eclipse.gef.palette.PaletteEntry; import org.eclipse.gef.palette.PaletteGroup; import org.eclipse.gef.palette.PaletteListener; import org.eclipse.gef.palette.PaletteRoot; import org.eclipse.gef.palette.SelectionToolEntry; import org.eclipse.gef.palette.ToolEntry; import org.eclipse.gef.ui.palette.PaletteViewer; import org.eclipse.gmf.runtime.common.ui.services.icon.IconService; import org.eclipse.gmf.runtime.diagram.ui.internal.services.palette.PaletteToolEntry; import org.eclipse.gmf.runtime.diagram.ui.tools.CreationTool; import org.eclipse.gmf.runtime.emf.type.core.IElementType; import org.eclipse.gmf.runtime.gef.ui.internal.palette.PaletteStack; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.RGB; /** * This is the default popup bar editpolicy installed on diagrams. The popup bar * is populated using the element types of the tools of the palette drawer of * the last selected palette tool. If the diagram was just opened, the popup bar * is populated using the element types of the tools of the palette drawer that * is initially open. If there is no drawer initially open, then * <code>fillWithDefaults()</code> is called to initially populate the popup * bar. * * @author cmahoney */ public class DiagramPopupBarEditPolicy extends PopupBarEditPolicy implements PaletteListener { /** * Holds the last active palette tool. */ private ToolEntry theLastTool = null; /* * (non-Javadoc) * * @see org.eclipse.gef.EditPolicy#activate() */ public void activate() { super.activate(); addPaletteListener(); } /* * (non-Javadoc) * * @see org.eclipse.gef.EditPolicy#deactivate() */ public void deactivate() { removePaletteListener(); super.deactivate(); } /* * (non-Javadoc) * * @see org.eclipse.gmf.runtime.diagram.ui.editpolicies.PopupBarEditPolicy#fillActionDescriptors() */ protected void fillPopupBarDescriptors() { fillBasedOnLastActivePaletteTool(); if (getPopupBarDescriptors().isEmpty()) { fillBasedOnOpenPaletteDrawer(); if (getPopupBarDescriptors().isEmpty()) { fillWithDefaults(); } } } /* * (non-Javadoc) * * @see org.eclipse.gef.palette.PaletteListener#activeToolChanged(org.eclipse.gef.ui.palette.PaletteViewer, * org.eclipse.gef.palette.ToolEntry) */ public void activeToolChanged(PaletteViewer palette, ToolEntry tool) { if (!(tool instanceof SelectionToolEntry)) { theLastTool = tool; } } /** * Adds this edit policy as a palette listener. */ private void addPaletteListener() { PaletteViewer paletteViewer = getHost().getViewer().getEditDomain() .getPaletteViewer(); if (paletteViewer != null) { paletteViewer.addPaletteListener(this); } } /** * Removes this edit policy as a palette listener. */ private void removePaletteListener() { PaletteViewer paletteViewer = getHost().getViewer().getEditDomain() .getPaletteViewer(); if (paletteViewer != null) { paletteViewer.removePaletteListener(this); } theLastTool = null; } /** * Adds popup bar descriptors for all the shape tools in the palette * container of the last active palette tool. Subclasses may override if * they wish to customize this behavior for their diagram. */ protected void fillBasedOnLastActivePaletteTool() { if (theLastTool == null) return; // Find the palette group or drawer containing the last active tool. PaletteContainer container = theLastTool.getParent(); if (container == null) { return; } while (!(container instanceof PaletteDrawer) && !(container instanceof PaletteGroup) && !(container instanceof PaletteRoot) && container.getParent() != null) { container = container.getParent(); } // Make sure the palette container is still in the palette root and has // not been removed. See bugzilla#176752. PaletteRoot realPaletteRoot = getHost().getViewer().getEditDomain() .getPaletteViewer().getPaletteRoot(); PaletteContainer paletteRoot = container; boolean sameRoot = false; while (paletteRoot != null) { paletteRoot = paletteRoot.getParent(); if (paletteRoot == realPaletteRoot) { sameRoot = true; break; } } if (sameRoot) { fillWithPaletteToolsInContainer(container); } } /** * Adds popup bar descriptors for all the shape tools in the given palette * container. Subclasses may override if they wish to customize this * behavior for their diagram. * * @param palContainer * the <code>PaletteContainer</code> */ protected void fillWithPaletteToolsInContainer(PaletteContainer palContainer) { if (palContainer != null) { List theEntries = palContainer.getChildren(); int isz = theEntries.size(); for (int i = 0; i < isz; i++) { PaletteEntry theEntry = (PaletteEntry) theEntries.get(i); if (theEntry != null) { if (theEntry instanceof PaletteToolEntry) { PaletteToolEntry theXtoolsEntry = (PaletteToolEntry) theEntry; Tool tempTool = theXtoolsEntry.createTool(); if ((tempTool != null) && (tempTool instanceof CreationTool)) { CreationTool theXtoolsTool = (CreationTool) tempTool; IElementType theToolType = theXtoolsTool .getElementType(); if ((theToolType != null)) { Image image = IconService.getInstance().getIcon(theToolType); // Workaround for mirroring and SWT.ICON issue if (image != null && image.type == SWT.ICON && isMirrored()) { image = convert(image); } addPopupBarDescriptor(theToolType, image); } } } else if (theEntry instanceof PaletteStack) { // add all the entries from a palette stack as well PaletteStack theStack = (PaletteStack) theEntry; fillWithPaletteToolsInContainer(theStack); } } } } } private boolean isMirrored() { return ((getHost().getViewer().getControl().getStyle() & SWT.MIRRORED) != 0); } private Image convert( Image srcImage) { int height = srcImage.getBounds().height; int width = srcImage.getBounds().width; ImageData srcImageData = srcImage.getImageData(); RGB backgroundRGB = ((GraphicalEditPart) getHost()).getFigure().getBackgroundColor().getRGB(); int backgroundColor = srcImageData.palette.getPixel(backgroundRGB); // Set the transparent pixels to the background color int count = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (((srcImageData.maskData[count>>3] >> (7-(count % 8))) & 1) == 0) { srcImageData.setPixel(x, y, backgroundColor); } count++; } } srcImageData.maskData = null; Image convertedImage = ImageDescriptor.createFromImageData(srcImageData).createImage(srcImage.getDevice()); imagesToBeDisposed.add(convertedImage); return convertedImage; } /** * Adds popup bar descriptors for all the shape tools in the palette drawer * that is initially open. Subclasses may override if they wish to customize * this behavior for their diagram. */ protected void fillBasedOnOpenPaletteDrawer() { PaletteViewer paletteViewer = getHost().getViewer().getEditDomain() .getPaletteViewer(); if (paletteViewer != null) { for (Iterator iter = paletteViewer.getPaletteRoot().getChildren() .iterator(); iter.hasNext();) { Object child = iter.next(); if (child instanceof PaletteDrawer) { PaletteDrawer drawer = (PaletteDrawer) child; if (drawer.isInitiallyOpen()) { fillWithPaletteToolsInContainer(drawer); break; } } } } } /** * Subclasses can override to provide default tools if the popup bar cannot * be populated based on the state of the palette. */ protected void fillWithDefaults() { // by default, add no popup bar descriptors. } }