| /******************************************************************************* |
| * Copyright (c) 2000, 2010 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.draw2d; |
| |
| import java.util.Map; |
| |
| import org.eclipse.swt.graphics.GC; |
| |
| import org.eclipse.draw2d.geometry.Rectangle; |
| |
| /** |
| * Update managers handle the job of laying out and repainting figures. A |
| * desirable implementation is to batches work to be done and collapses any |
| * redundant work. For example, clients may be making multiple changes to |
| * figures, which require laying out the same container or repainting the same |
| * region. |
| * <P> |
| * The update manager receives requests to validate certain figures, and repaint |
| * certain areas of figures. An update manager could process every request |
| * synchronously, or it could batch these requests and process them |
| * asynchronously. |
| * <P> |
| * The update process occurs in two phases. The first phase is laying out |
| * invalid figures. This phase comes first because it usually introduces |
| * additional damage regions. In some cases, while validating figures, new |
| * invalid figures may be appended to the update manager. Of course, damage |
| * regions will be reported too as figures are layed out. |
| * <P> |
| * The second phase is to repaint all damaged areas. The update manager will |
| * typically batch, clip, and union, all rectangles and perform a single paint |
| * of the overall damaged area. |
| * |
| */ |
| public abstract class UpdateManager { |
| |
| private UpdateListener listeners[] = new UpdateListener[0]; |
| private boolean disposed; |
| |
| /** |
| * Adds the dirty region defined by the coordinates on the IFigure |
| * <b>figure</b>. The update manager should repaint the dirty region in a |
| * timely fashion. |
| * |
| * @param figure |
| * the dirty figure |
| * @param x |
| * the x coordinate of the dirty region |
| * @param y |
| * the y coordinate of the dirty region |
| * @param w |
| * the width of the dirty region |
| * @param h |
| * the height of the dirty region |
| */ |
| public abstract void addDirtyRegion(IFigure figure, int x, int y, int w, |
| int h); |
| |
| /** |
| * @see #addDirtyRegion(IFigure, int, int, int, int) |
| */ |
| public void addDirtyRegion(IFigure figure, Rectangle rect) { |
| addDirtyRegion(figure, rect.x, rect.y, rect.width, rect.height); |
| } |
| |
| /** |
| * Causes an update to occur at some time, and the given runnable to be |
| * executed following the update. |
| * |
| * @since 3.1 |
| * @param run |
| * the runnable |
| */ |
| public void runWithUpdate(Runnable run) { |
| } |
| |
| /** |
| * The receiver should call validate() on the IFigure <i>figure</i> in a |
| * timely fashion. |
| * |
| * @param figure |
| * the invalid figure |
| */ |
| public abstract void addInvalidFigure(IFigure figure); |
| |
| /** |
| * Adds the given listener to the list of listeners to be notified of |
| * painting and validation. |
| * |
| * @param listener |
| * the listener to add |
| */ |
| public void addUpdateListener(UpdateListener listener) { |
| if (listener == null) |
| throw new IllegalArgumentException(); |
| if (listeners == null) { |
| listeners = new UpdateListener[1]; |
| listeners[0] = listener; |
| } else { |
| int oldSize = listeners.length; |
| UpdateListener newListeners[] = new UpdateListener[oldSize + 1]; |
| System.arraycopy(listeners, 0, newListeners, 0, oldSize); |
| newListeners[oldSize] = listener; |
| listeners = newListeners; |
| } |
| } |
| |
| /** |
| * Called when the EditPartViewer is being disposed. |
| */ |
| public void dispose() { |
| disposed = true; |
| } |
| |
| /** |
| * Notifies listeners that painting is about to occur, passing them the |
| * damaged rectangle and the map of dirty regions. |
| * |
| * @param damage |
| * the damaged rectangle |
| * @param dirtyRegions |
| * map of dirty regions to figures |
| */ |
| protected void firePainting(Rectangle damage, Map dirtyRegions) { |
| UpdateListener localListeners[] = listeners; |
| for (int i = 0; i < localListeners.length; i++) |
| localListeners[i].notifyPainting(damage, dirtyRegions); |
| } |
| |
| /** |
| * Notifies listeners that validation is about to occur. |
| */ |
| protected void fireValidating() { |
| UpdateListener localListeners[] = listeners; |
| for (int i = 0; i < localListeners.length; i++) |
| localListeners[i].notifyValidating(); |
| } |
| |
| /** |
| * @return whether this update manager has been disposed. |
| */ |
| protected boolean isDisposed() { |
| return disposed; |
| } |
| |
| /** |
| * Forces an update to occur. Update managers will perform updates |
| * automatically, but may do so asynchronously. Calling this method forces a |
| * synchronous update. |
| */ |
| public abstract void performUpdate(); |
| |
| void paint(GC gc) { |
| performUpdate(new Rectangle(gc.getClipping())); |
| } |
| |
| /** |
| * Performs an update on the given exposed rectangle. |
| * |
| * @param exposed |
| * the exposed rectangle |
| */ |
| public abstract void performUpdate(Rectangle exposed); |
| |
| /** |
| * Removes one occurrence of the given UpdateListener by identity. |
| * |
| * @param listener |
| * the listener to remove |
| */ |
| public void removeUpdateListener(UpdateListener listener) { |
| if (listener == null) |
| throw new IllegalArgumentException(); |
| for (int index = 0; index < listeners.length; index++) |
| if (listeners[index] == listener) { |
| int newSize = listeners.length - 1; |
| UpdateListener newListeners[] = null; |
| if (newSize != 0) { |
| newListeners = new UpdateListener[newSize]; |
| System.arraycopy(listeners, 0, newListeners, 0, index); |
| System.arraycopy(listeners, index + 1, newListeners, index, |
| newSize - index); |
| } else { |
| newListeners = new UpdateListener[0]; |
| } |
| listeners = newListeners; |
| return; |
| } |
| } |
| |
| /** |
| * Sets the GraphicsSource for this update manager. |
| * |
| * @param gs |
| * the new GraphicsSource |
| */ |
| public abstract void setGraphicsSource(GraphicsSource gs); |
| |
| /** |
| * Sets the root figure. |
| * |
| * @param figure |
| * the new root figure |
| */ |
| public abstract void setRoot(IFigure figure); |
| |
| /** |
| * Performs a partial update if supported (validation only). Fires |
| * notification to listeners that validation has been performed. By default |
| * this method calls {@link #performUpdate()}. Subclasses should override |
| * this method to support validation without repainting. |
| * |
| * @since 3.2 |
| */ |
| public void performValidation() { |
| performUpdate(); |
| } |
| |
| } |