blob: 9b13081de2bc5b0ff10b8e88eb41d0419ea44d76 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005 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.bpel.common.ui.tray;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.bpel.common.ui.ICommonUIConstants;
import org.eclipse.bpel.common.ui.CommonUIPlugin;
import org.eclipse.bpel.common.ui.details.IDetailsColors;
import org.eclipse.bpel.common.ui.details.widgets.NoBorderButton;
import org.eclipse.draw2d.AbstractLayout;
import org.eclipse.draw2d.ActionEvent;
import org.eclipse.draw2d.ActionListener;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.ImageFigure;
import org.eclipse.draw2d.KeyEvent;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.DragTracker;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.Handle;
import org.eclipse.gef.Request;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gef.requests.CreateRequest;
import org.eclipse.gef.requests.CreationFactory;
import org.eclipse.gef.requests.GroupRequest;
import org.eclipse.gef.tools.SelectEditPartTracker;
/**
* Represents a category in the Tray.
*/
public abstract class TrayCategoryEditPart extends TrayContainerEditPart {
protected SelectionBorderFigure titleFigure;
protected class TrayCategoryEntrySelectionEditPolicy extends TraySelectionEditPolicy {
@Override
protected Handle createHandle(GraphicalEditPart owner) {
return new TraySelectionHandle(owner, titleFigure);
}
}
/**
* A layout for the title of this edit part:
* ICON LABEL ADD_BUTTON REMOVE_BUTTON
*/
protected class TitleLayout extends AbstractLayout {
private static final int SPACING = 2;
public void layout(IFigure container) {
List elements = container.getChildren();
ImageFigure icon = (ImageFigure)elements.get(0);
Label text = (Label)elements.get(1);
Figure removeButton = (Figure)elements.get(2);
Figure addButton = (Figure)elements.get(3);
Rectangle containerBounds = container.getBounds();
int x = containerBounds.x + SPACING;
int y = containerBounds.y;
int height = containerBounds.height;
Dimension size = icon.getPreferredSize();
Rectangle bounds = new Rectangle(x, y, size.width, height);
icon.setBounds(bounds);
size = removeButton.getPreferredSize();
x = (containerBounds.x + containerBounds.width) - size.width;
bounds = new Rectangle(x, y, size.width, height);
removeButton.setBounds(bounds);
size = addButton.getPreferredSize();
x = x - size.width;
bounds = new Rectangle(x, y, size.width, height);
addButton.setBounds(bounds);
x = icon.getBounds().x + icon.getBounds().width;
x = x + SPACING;
int width = containerBounds.width - (icon.getBounds().width + removeButton.getBounds().width + addButton.getBounds().width);
bounds = new Rectangle(x, y, width, height);
text.setBounds(bounds);
}
@Override
protected Dimension calculatePreferredSize(IFigure container, int wHint, int hHint) {
Dimension result = new Dimension(0, hHint);
for (Iterator<IFigure> iter = container.getChildren().iterator(); iter.hasNext();) {
IFigure child = iter.next();
Dimension size = (child instanceof Label) ? child.getMinimumSize() : child.getPreferredSize();
result.height = Math.max(result.height, size.height);
result.width += size.width;
}
result.height += (SPACING*2); // give it some extra pixels
return result;
}
}
/**
* The figure representing the title of this container.
*/
protected class TitleFigure extends SelectionBorderFigure {
protected Label textLabel;
protected NoBorderButton addButton;
protected NoBorderButton removeButton;
public TitleFigure() {
super();
setLayoutManager(new TitleLayout());
setOpaque(true);
setBackgroundColor(CommonUIPlugin.getDefault().getColorRegistry().get(IDetailsColors.COLOR_LIGHT_BACKGROUND));
add(new ImageFigure(getLabelProvider().getImage(getModel())));
textLabel = new Label(getLabelProvider().getText(getModel()));
textLabel.setLabelAlignment(PositionConstants.LEFT);
add(textLabel);
removeButton = new NoBorderButton(CommonUIPlugin.getDefault().getImageRegistry().get(ICommonUIConstants.ICON_TRAY_CATEGORY_REMOVE_BUTTON)) {
@Override
public void handleKeyPressed(KeyEvent event) {
// Do nothing - the button can only be pressed with a mouse
}
@Override
public void handleKeyReleased(KeyEvent event) {
// Do nothing - the button can only be pressed with a mouse
}
};
removeButton.setOpaque(false);
removeButton.setToolTip(getRemoveToolTip());
removeButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
removeEntry();
}
});
addButton = new NoBorderButton(CommonUIPlugin.getDefault().getImageRegistry().get(ICommonUIConstants.ICON_TRAY_CATEGORY_ADD_BUTTON)) {
@Override
public void handleKeyPressed(KeyEvent event) {
// Do nothing - the button can only be pressed with a mouse
}
@Override
public void handleKeyReleased(KeyEvent event) {
// Do nothing - the button can only be pressed with a mouse
}
};
addButton.setOpaque(false);
addButton.setToolTip(getAddToolTip());
addButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
addEntry();
}
});
add(removeButton);
add(addButton);
}
public Label getTextLabel() {
return textLabel;
}
}
/**
* Adds a new entry to the category. Returns the new model object.
*/
protected Object addEntry() {
CreateRequest request = new CreateRequest();
request.setFactory(getCreationFactory());
Command command = getCommand(request);
getCommandStack().execute(command);
Object newObject = request.getNewObject();
// Select the new item after creation
selectEditPart(newObject);
return newObject;
}
/**
* Adds a new entry to the category. Returns the new model object.
* Used by the AddChildInTrayAction.
*/
public Object publicAddEntry() {
return addEntry();
}
/**
* Called by the remove button to remove the currently selected entry.
*/
protected void removeEntry() {
List selectedParts = getViewer().getSelectedEditParts();
if (selectedParts.size() == 0) return; // nothing to be done
// we can only delete edit parts that are children of this edit part
List<EditPart> condemned = new ArrayList<EditPart>();
for (Iterator<EditPart> iter = selectedParts.iterator(); iter.hasNext();) {
EditPart part = iter.next();
if (part.getParent() == TrayCategoryEditPart.this) {
condemned.add(part);
}
}
if (condemned.isEmpty()) return; // nothing to be done
// gets the index to be used in the post-deletion selection
EditPart indexPart = condemned.get(0);
int index = getModelChildren().indexOf(indexPart.getModel());
// remove all the valid selected edit parts
GroupRequest request = new GroupRequest(RequestConstants.REQ_DELETE);
CompoundCommand deletions = new CompoundCommand();
for (Iterator<EditPart> iter = condemned.iterator(); iter.hasNext();) {
EditPart part = iter.next();
deletions.add(part.getCommand(request));
}
getCommandStack().execute(deletions);
// Select the next edit part if one is available
int size = getModelChildren().size();
if (size == 0) return; // nothing to be done
if (size > index) {
selectEditPart(getModelChildren().get(index));
} else {
selectEditPart(getModelChildren().get(size-1));
}
}
public TrayCategoryEditPart() {
super();
}
@Override
protected TrayContainerFigure createMainFigure() {
return new TrayContainerFigure() {
@Override
protected void paintBorder(Graphics graphics) {
graphics.setForegroundColor(CommonUIPlugin.getDefault().getColorRegistry().get(IDetailsColors.COLOR_DARK_SHADOW));
Rectangle area = getClientArea().getCopy();
area.height--;
graphics.drawLine(area.getTopLeft(), area.getTopRight());
}
};
}
@Override
protected IFigure createTitleFigure() {
return titleFigure = new TitleFigure();
}
/**
* As part of our layout, the entries and the category should have
* the same x-coordinate for their texts. This is the figure used
* by the entries to calculate the position of their text.
*/
public IFigure getLabelPositionReference() {
return ((TitleFigure)getTitleFigure()).getTextLabel();
}
@Override
protected void createEditPolicies() {
installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE, new TrayCategoryEntrySelectionEditPolicy());
}
/**
* Subclasses need to provide a creation factory for the category entry creation.
*/
protected abstract CreationFactory getCreationFactory();
/* (non-Javadoc)
* @see org.eclipse.gef.EditPart#getDragTracker(org.eclipse.gef.Request)
*/
@Override
public DragTracker getDragTracker(Request request) {
return new SelectEditPartTracker(this);
}
@Override
public Label getDirectEditLabel() {
return null;
}
/**
* Return the label to be used as the tooltip for the Add button.
* Subclasses may override.
*/
protected IFigure getAddToolTip() {
return new Label("Add");
}
/**
* Return the label to be used as the tooltip for the Add button.
* Subclasses may override.
*/
protected IFigure getRemoveToolTip() {
return new Label("Remove");
}
}