/******************************************************************************* * 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.ArrayList; import java.util.List; import java.util.TreeMap; import org.eclipse.draw2d.IFigure; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.zest.custom.sequence.widgets.UMLItem; import org.eclipse.zest.custom.sequence.widgets.internal.IWidgetProperties; /** * Represents the visuals of a draw2d widget. * @author Del Myers */ public abstract class WidgetVisualPart { private UMLItem item; private String key; private IFigure figure; private WidgetDisposeListener disposeListener; private boolean active; //experimental: fields to try and speed up refreshing // private WidgetVisualPart leftSibling; // private WidgetVisualPart rightSibling; /** * Used to decorate the visual with certain properties to check different states. * Use decorations on the visuals instead of on the widget when you don't want listeners * to be notified of property changes due to setData() on the widget. */ private TreeMap<String, Object> decorations; private final class WidgetDisposeListener implements DisposeListener { /* (non-Javadoc) * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent) */ public void widgetDisposed(DisposeEvent e) { deactivate(); } } public WidgetVisualPart(UMLItem item, String key) { this.item = item; this.active = false; this.key = key; this.disposeListener = new WidgetDisposeListener(); this.decorations = new TreeMap<String, Object>(); } /** * Creates all of the figures for this visual. It is possible that the visual may install multiple * figures in that case, then getFigures() will return a list of all the figures. This returns * the primary figure that is created. * @return the primary figure for this visual. */ public abstract IFigure createFigures(); /** * Returns a list of all of the figures created by this visual that have to be registered and * installed. By default, the visual only has one primary figure. This method will return * a list containing that figure. * @return */ public List<IFigure> getFigures() { ArrayList<IFigure> list = new ArrayList<IFigure>(1); list.add(getFigure()); return list; } /** * Returns the main figure for this visual. * @return */ public IFigure getFigure() { if (this.figure == null) { this.figure = createFigures(); } return this.figure; } public void activate() { if (isActive()) return; if (item.isDisposed()) return; item.setData(key, this); item.addDisposeListener(disposeListener); registerVisuals(); //installFigures(); active = true; item.setData(IWidgetProperties.ACTIVE, true); //refreshVisuals(); } public void deactivate() { if (!isActive()) return; if (!item.isDisposed()) { item.removeDisposeListener(disposeListener); } deregisterVisuals(); uninstallFigures(); active = false; if (!item.isDisposed()) { item.setData(IWidgetProperties.ACTIVE, null); } } protected void deregisterVisuals() { MessageBasedSequenceVisuals visuals = getChartVisuals(); if (visuals != null) { visuals.deregister(this); } } protected void registerVisuals() { MessageBasedSequenceVisuals visuals = getChartVisuals(); if (visuals != null) { visuals.register(this); } } /** * @return the active */ public boolean isActive() { return active; } public UMLItem getWidget() { return item; } public abstract void refreshVisuals(); public IFigure getLayer(Object key) { return getChartVisuals().getLayer(key); } /** * @return the key */ public String getKey() { return key; } public MessageBasedSequenceVisuals getChartVisuals() { return (MessageBasedSequenceVisuals) getWidget().getChart().getData(MessageBasedSequenceVisuals.VISUAL_KEY); } /** * Installs the figures for this visual part into their parent. The layers for containment of * the figures can be retrieved using getLayer(key) where key is usually one of the keys defined * in LayerConstants. By default, only the primary figure is installed. */ protected void installFigures() { IFigure layer = getLayer(LayerConstants.PRIMARY_LAYER); if (layer != null) { layer.add(getFigure()); } } /** * Removes the figures created by this visual from their parents. By default, only the primary * figure is uninstalled. */ protected void uninstallFigures() { IFigure figure = getFigure(); if (figure != null && figure.getParent() != null) { figure.getParent().remove(figure); } } /** * Marks this visual with the given data, so that it can be used by other applications to * check if the visual is in a particular state without the overhead of using the setData() method * in the widget contained in this visual. * @param key the key to store the data under. * @param value the value to store there. */ public void decorate(String key, Object value) { decorations.put(key, value); } /** * Returns the decoration stored under the given key, or null if it is not present. * @param key the key to get the decoration from. * @return the decoration, or null. */ public Object getDecoration(String key) { return decorations.get(key); } /** * Removes the decoration associated with the given key, and returns what was previously stored * or null, if it wasn't present. * @param key the key to clear. * @return the value previously stored with the key, or null. */ public Object clearDecoration(String key) { return decorations.remove(key); } }