/*******************************************************************************
* Copyright (c) 2009 the CHISEL group and contributors.
* 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:
* Del Myers -- initial API and implementation
*******************************************************************************/
package org.eclipse.zest.custom.sequence.visuals;
import java.util.HashMap;
import java.util.Iterator;
import org.eclipse.draw2d.FigureListener;
import org.eclipse.draw2d.FreeformLayer;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Polyline;
import org.eclipse.draw2d.RectangleFigure;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Display;
import org.eclipse.zest.custom.sequence.events.SequenceEvent;
import org.eclipse.zest.custom.sequence.events.SequenceListener;
import org.eclipse.zest.custom.sequence.widgets.Activation;
import org.eclipse.zest.custom.sequence.widgets.Call;
import org.eclipse.zest.custom.sequence.widgets.Message;
import org.eclipse.zest.custom.sequence.widgets.UMLItem;
/**
*
* A manager for highlighting selections and mouse-overs.
* @author Del Myers
*
*/
public class SelectionDecorationLayer implements SelectionListener, SequenceListener, FigureListener {
private HashMap<UMLItem, IFigure> pinnedFigures;
private MessageBasedSequenceVisuals visuals;
private FreeformLayer layer;
public SelectionDecorationLayer(MessageBasedSequenceVisuals visuals) {
this.visuals = visuals;
pinnedFigures = new HashMap<UMLItem, IFigure>();
visuals.getChart().addSelectionListener(this);
visuals.getChart().addSequenceListener(this);
}
/* (non-Javadoc)
* @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
*/
public void widgetDefaultSelected(SelectionEvent e) {
updateSelection();
}
/* (non-Javadoc)
* @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
*/
public void widgetSelected(SelectionEvent e) {
updateSelection();
}
/* (non-Javadoc)
* @see org.eclipse.zest.custom.sequence.events.SequenceListener#itemCollapsed(org.eclipse.zest.custom.sequence.events.SequenceEvent)
*/
public void itemCollapsed(SequenceEvent event) {
updateSelection();
}
/* (non-Javadoc)
* @see org.eclipse.zest.custom.sequence.events.SequenceListener#itemExpanded(org.eclipse.zest.custom.sequence.events.SequenceEvent)
*/
public void itemExpanded(SequenceEvent event) {
updateSelection();
}
/* (non-Javadoc)
* @see org.eclipse.zest.custom.sequence.events.SequenceListener#rootChanged(org.eclipse.zest.custom.sequence.events.SequenceEvent)
*/
public void rootChanged(SequenceEvent event) {
updateSelection();
}
public void refresh() {
updateSelection();
}
private void updateSelection() {
for (UMLItem pinnedItem : pinnedFigures.keySet()) {
IFigure itemFigure = visuals.getFigure(pinnedItem);
IFigure pinFigure = pinnedFigures.get(pinnedItem);
if (pinFigure.getParent() != null) {
pinFigure.getParent().remove(pinFigure);
}
if (itemFigure != null) {
itemFigure.removeFigureListener(this);
}
}
pinnedFigures.clear();
for (UMLItem item : visuals.getChart().getSelection()) {
if (item instanceof Activation) {
pin ((Activation)item);
} else if (item instanceof Message) {
pin ((Message)item);
}
}
}
/**
* @param message
*/
private void pin(Message item) {
if (!item.isVisible()) return;
if (pinnedFigures.containsKey(item)) return;
Polyline figure = new Polyline(){
/* (non-Javadoc)
* @see org.eclipse.draw2d.Figure#paint(org.eclipse.draw2d.Graphics)
*/
@Override
public void paint(Graphics graphics) {
graphics.pushState();
graphics.setAlpha(150);
setLineWidth(4);
graphics.setForegroundColor(Display.getCurrent().getSystemColor(SWT.COLOR_LIST_SELECTION));
super.paint(graphics);
graphics.popState();
}
};
figure.setOpaque(true);
IFigure itemFigure = visuals.getFigure(item);
if (itemFigure != null) {
pinnedFigures.put(item, figure);
getLayer().add(figure);
figureMoved(itemFigure);
itemFigure.addFigureListener(this);
}
if (item instanceof Call) {
pin(item.getTarget());
}
}
/**
* @param item
*/
private void pin(Activation item) {
if (!item.isVisible()) return;
if (pinnedFigures.containsKey(item)) return;
RectangleFigure figure = new RectangleFigure(){
/* (non-Javadoc)
* @see org.eclipse.draw2d.Figure#paint(org.eclipse.draw2d.Graphics)
*/
@Override
public void paint(Graphics graphics) {
graphics.pushState();
graphics.setAlpha(100);
super.paint(graphics);
graphics.popState();
}
};
figure.setOpaque(true);
figure.setFill(true);
figure.setLineWidth(1);
figure.setForegroundColor(Display.getCurrent().getSystemColor(SWT.COLOR_LIST_SELECTION));
figure.setBackgroundColor(Display.getCurrent().getSystemColor(SWT.COLOR_LIST_SELECTION));
IFigure itemFigure = visuals.getFigure(item);
if (itemFigure != null) {
pinnedFigures.put(item, figure);
getLayer().add(figure);
figureMoved(itemFigure);
itemFigure.addFigureListener(this);
}
if (item.isExpanded()) {
for (Message m : item.getMessages()) {
pin(m);
}
}
}
public IFigure getLayer() {
if (this.layer == null) {
this.layer = new FreeformLayer();
layer.setEnabled(false);
}
return layer;
}
/* (non-Javadoc)
* @see org.eclipse.draw2d.FigureListener#figureMoved(org.eclipse.draw2d.IFigure)
*/
public void figureMoved(IFigure source) {
UMLItem item = (UMLItem) visuals.getWidget(source);
if (item == null) {
//this is stale, have to remove the listener.
source.removeFigureListener(this);
for (Iterator<UMLItem> itemIterator = pinnedFigures.keySet().iterator(); itemIterator.hasNext();) {
UMLItem pinnedItem = itemIterator.next();
if (visuals.getFigure(pinnedItem) == source) {
IFigure pinFigure = pinnedFigures.get(pinnedItem);
if (pinFigure.getParent() != null) {
pinFigure.getParent().remove(pinFigure);
}
itemIterator.remove();
}
}
} else {
if (item instanceof Activation) {
RectangleFigure figure = (RectangleFigure) pinnedFigures.get(item);
IFigure itemFigure = visuals.getFigure(item);
if (figure != null && itemFigure != null) {
figure.setBounds(itemFigure.getBounds().getCopy());
}
} else if (item instanceof Message) {
Polyline line = (Polyline)pinnedFigures.get(item);
Polyline itemLine = (Polyline)visuals.getFigure(item);
line.setPoints(itemLine.getPoints().getCopy());
}
}
}
public String getLayerKey() {
return "SelectionDecoration";
}
}