org.eclipse.gmf.runtime.diagram.ui.editpolicies.DiagramPopupBarEditPolicy.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.gmf.runtime.diagram.ui.editpolicies.DiagramPopupBarEditPolicy.java

Source

/******************************************************************************
 * 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.
    }

}