/******************************************************************************* * 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.figures.internal; import java.util.Map; import org.eclipse.draw2d.DeferredUpdateManager; import org.eclipse.draw2d.UpdateListener; import org.eclipse.draw2d.geometry.Rectangle; /** * An update manager that allows all updates to be suspended. Work will still get * queued, but updates will not be performed until the manager is resumed. * @author Del Myers * */ public class SuspendableDeferredUpdateManager extends DeferredUpdateManager { /** * State variable indicated whether or not this update manager is suspended. */ private volatile boolean suspended; private UpdateListener[] listeners; public SuspendableDeferredUpdateManager() { super(); listeners = new UpdateListener[0]; suspended = false; } /** * Sets the state of this update manager to suspended. Updates will not be * performed until resume() is called. */ public void suspend() { this.suspended = true; } /** * Performs queued updates, and allows new updates to be performed. */ public void resume() { if (!isSuspended()) { return; } suspended = false; sendUpdateRequest(); } /** * This implementation only sends update requests if the manager is not suspended. */ @Override protected void sendUpdateRequest() { if (isSuspended()) return; super.sendUpdateRequest(); } /** * Returns true if this update manager is not sending update requests. * @return true if this update manager is not sending update requests. */ public boolean isSuspended() { return suspended; } /** * 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; } } /** * Removes one occurence 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[] = new UpdateListener[newSize]; if (newSize != 0) { System.arraycopy(listeners, 0, newListeners, 0, index); System.arraycopy(listeners, index + 1, newListeners, index, newSize - index); } listeners = newListeners; return; } } /** * 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 */ @SuppressWarnings("unchecked") 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(); } }