blob: 9056b6ef7e5431ea411f805321b03e354511c8e1 [file] [log] [blame]
/*******************************************************************************
* 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();
}
}